package cz.data.common.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;

@Slf4j
public class InMemoryRequestMatcherRepository extends AbstractRequestMatcher {
    private final Map<String, MvcRequestMatcher> matcherMap = new ConcurrentHashMap<>();
    private final BiFunction<String, String, MvcRequestMatcher> createMatcherFun;

    public InMemoryRequestMatcherRepository(BiFunction<String, String, MvcRequestMatcher> createMatcherFun) {
        this.createMatcherFun = createMatcherFun;
    }

    @Override
    protected boolean doMatches(HttpServletRequest request) {
        Collection<MvcRequestMatcher> matchers = matcherMap.values();
        return matchers.stream().anyMatch(rule -> rule.matches(request));
    }

    @Override
    public synchronized void register(String method, String requestUrl) {
        String matcherKey = buildMatcherKey(method, requestUrl);
        MvcRequestMatcher matcher = createMatcherFun.apply(method, requestUrl);
        matcherMap.put(matcherKey, matcher);
    }

    @Override
    public synchronized void unRegister(String method, String requestUrl) {
        String matcherKey = buildMatcherKey(method, requestUrl);
        matcherMap.remove(matcherKey);
    }

    private String buildMatcherKey(String method, String requestUrl) {
        return method + ":" + requestUrl;
    }
}
